﻿#region copyright
//<copyright>
// Copyright(C) 2012 TrackerRealm Corporation
// This file is part of the open source project - Jazz. http://jazz.codeplex.com
// 
// Jazz is open software: you can redistribute it and/or modify it 
// under the terms of the GNU Affero General Public License (AGPL) as published by 
// the Free Software Foundation, version 3 of the License.
// 
// Jazz is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty 
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
//  See the GNU Affero General Public License (AGPL) for more details.
// 
// You should have received a copy of the GNU General Public 
// License along with Jazz.  If not, see <http://www.gnu.org/licenses/>.
//
// REMOVAL OF THIS NOTICE IS VIOLATION OF THE COPYRIGHT. 
//</copyright>
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.Serialization;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using TrackerRealm.Jazz.Common;
using TrackerRealm.Jazz.Client;
using TrackerRealm.Jazz.Client.Services;

namespace TrackerRealm.Jazz.Json
{
    /// <summary>
    /// 
    /// </summary>
    public class jObjectReferenceConverter : JsonConverter
    {
        SerializerService serialService;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="service"></param>
        public jObjectReferenceConverter(SerializerService service) 
        {
            this.serialService = service;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="serializer"></param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            jObject jazzObj = (jObject)value;
            // ID
            writer.WriteStartObject();
            writer.WritePropertyName("$refid");
            writer.WriteValue(jazzObj.ID);
            // ClassName
            Type t = jazzObj.GetType();
            writer.WritePropertyName("ClassName");
            writer.WriteValue(t.FullName);
            // AssemblyName - if required
            string s = t.Assembly.FullName;
            string[] sArray = s.Split(',');
            if (sArray[0] != JazzServices.GetNamespaceFromFullClassName(t.FullName))
            {
                writer.WritePropertyName("AssemblyName");
                writer.WriteValue(sArray[0]);  // just the name
            }
            writer.WriteEndObject();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="objectType"></param>
        /// <param name="existingValue"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            // ID
            reader.Read();
            string p_id = (string)reader.Value;
            reader.Read();
            Guid id = (Guid)serializer.Deserialize(reader, typeof(Guid));
            // Class Name
            reader.Read();
            string p_name = (string)reader.Value;
            reader.Read();
            string className = (string)reader.Value;
            //
            //
            reader.Read(); // read closing bracket
            string assemblyName = "";
            if ((string)reader.Value == "AssemblyName")
            {
                // AssemblyName
                string p_assemblyName = (string)reader.Value;
                reader.Read();
                assemblyName = (string)reader.Value;
                reader.Read(); // read closing bracket
            }

            Type t;
            if (assemblyName == "")
                t = JazzServices.GetTypeFromName(className);
            else
                t = JazzServices.GetTypeFromName(assemblyName, className);

            jObject jazzObj = this.serialService.Create(id, t);

            //reader.Read();  // read closing bracket
            return jazzObj;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public override bool CanConvert(Type objectType)
        {
            if (objectType == typeof(jObject))
                return true;
            return false;
        }
    }
}
